import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:fluttertoast/fluttertoast.dart';

import '../const.dart';

class MyDio {
  static final String GET = "GET";
  static final String POST = "POST";
  static final String CODE = "code";
  static var codes = {200};

  Dio dio;
  static MyDio _instance;

  static MyDio getInstance({String url}) {
    if (_instance == null) {
      _instance = MyDio(url: url);
    }
    return _instance;
  }

  MyDio({String url}) {
    var baseUrl;
    url == null ? baseUrl = Const.BASEURL : baseUrl = url;
    dio = Dio(BaseOptions(
      baseUrl: baseUrl,
//      headers: {HttpHeaders.contentTypeHeader: 'application/json'},
      connectTimeout: 15000,
      receiveTimeout: 15000,
      responseType: ResponseType.plain,
    ));
  }

  clearInstance() {
    _instance = null;
  }

  //get请求
  get(String url, Function successCallBack,
      {params, Function errorCallBack}) async {
    _requstHttp(url, successCallBack, GET, params, errorCallBack);
  }

  //post请求
  post(String url, Function successCallBack,
      {params, Function errorCallBack}) async {
    _requstHttp(url, successCallBack, POST, params, errorCallBack);
  }

  upload(String url, Function successCallBack,
      {params, Function errorCallBack}) async {
    _requstUpload(url, successCallBack, POST, params, errorCallBack);
  }

  _requstHttp(String url, Function successCallBack,
      [String method,
      Map<String, dynamic> params,
      Function errorCallBack]) async {
    String errorMsg = '';
    int code;

    try {
      Response response;
//      _addStartHttpInterceptor(dio); //添加请求之前的拦截器
      if (method == GET) {
        if (params != null && params.isNotEmpty) {
          var headers = Map<String, String>();
          headers[HttpHeaders.contentTypeHeader] = 'application/json';
          Options options = Options(
            headers: headers,
          );
          response =
              await dio.get(url, queryParameters: params, options: options);
        } else {
          response = await dio.get(url);
        }
      } else if (method == POST) {
        if (params != null && params.isNotEmpty) {
          var headers = Map<String, String>();
          headers[HttpHeaders.contentTypeHeader] = 'application/json';
          Options options = Options(
            headers: headers,
          );
          response = await dio.post(
            url,
            data: params,
            options: options,
          );
        } else {
          response = await dio.post(url);
        }
      }

      print('HttpResponse$response');

      code = response.statusCode;
      if (code != 200) {
        errorMsg = '错误码：' + code.toString() + '，' + response.data.toString();
        _error(errorCallBack, errorMsg);
        return;
      }

      Map<String, dynamic> dataMap = json.decode(response.toString());
      if (successCallBack != null) {
        successCallBack(dataMap);
      }
    } catch (exception) {
      print('error:$exception');
      _error(errorCallBack, exception.toString());
    }
  }

  _requstUpload(String url, Function successCallBack,
      [String method, FormData params, Function errorCallBack]) async {
    String errorMsg = '';
    int code;

    try {
      Response response;
      print('uploadurl:$url');
      response =
          await dio.post(url, data: params, onSendProgress: (send, total) {
        print('已发送：$send  总大小：$total');
      });
      print('HttpResponse$response');

      code = response.statusCode;
      if (code != 200) {
        errorMsg = '错误码：' + code.toString() + '，' + response.data.toString();
        _error(errorCallBack, errorMsg);
        return;
      }

      Map<String, dynamic> dataMap = json.decode(response.toString());
      if (successCallBack != null) {
        successCallBack(dataMap);
      }
    } catch (exception) {
      print('error:$exception');
      _error(errorCallBack, exception.toString());
    }
  }

  _error(Function errorCallBack, String error) {
    Fluttertoast.showToast(
        msg: error.toString(),
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER);
    if (errorCallBack != null) {
      errorCallBack(error);
    }
  }
}
